package com.touzhijia.authority.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.touzhijia.authority.domain.dto.request.*;
import com.touzhijia.authority.domain.dto.response.RoleByUserRes;
import com.touzhijia.authority.domain.dto.response.RolePermissionAddRes;
import com.touzhijia.authority.domain.entity.Permission;
import com.touzhijia.authority.domain.entity.Role;
import com.touzhijia.authority.exception.BusinessException;
import com.touzhijia.authority.mapper.PermissionMapper;
import com.touzhijia.authority.mapper.RoleMapper;
import com.touzhijia.authority.mapper.UserMapper;
import com.touzhijia.authority.utils.mapper.BeanMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Transactional(readOnly = true)
@Service
public class RoleService {
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private UserMapper userMapper;

    public Role getRole(String name) {
        return roleMapper.getByName(name);
    }

    public PageInfo<Role> findRole(RoleQueryReq queryReq) {
        return PageHelper
                .startPage(queryReq.getPageNo(), queryReq.getPageSize())
                .doSelectPageInfo(() -> roleMapper.findRole(queryReq));
    }

    public PageInfo<RoleByUserRes> findRoleByUser(RoleQueryByUserReq queryReq) {
        return PageHelper
                .startPage(queryReq.getPageNo(), queryReq.getPageSize())
                .doSelectPageInfo(() -> roleMapper.findRoleByUser(queryReq));
    }

    @Transactional
    public Role addRole(RoleAddReq roleAddReq) {
        Role exists = roleMapper.getByName(roleAddReq.getName());
        if (exists != null) {
            throw new BusinessException("角色已存在");
        }
        Role role = BeanMapper.mapper(roleAddReq, Role.class);
        role.setCreateAt(new Date());
        roleMapper.insertSelective(role);
        return role;
    }

    @Transactional
    public Role delRole(String name) {
        Role role = roleMapper.getByName(name);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }
        // 删除 role
        roleMapper.deleteByName(name);
        // 删除 user_role
        userMapper.deleteByRoleName(name);
        // 删除 role_permission
        roleMapper.deleteByRoleName(name);
        // TODO Spring Security 处理
        return role;
    }

    @Transactional
    public Role updateRole(String name, RoleUpdateReq updateReq) {
        Role role = roleMapper.getByName(name);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }
        Role update = BeanMapper.mapper(updateReq, Role.class);
        update.setId(role.getId());
        update.setUpdateAt(new Date());
        roleMapper.updateByPrimaryKeySelective(update);
        return roleMapper.getByName(name);
    }

    @Transactional
    public RolePermissionAddRes addRolePermission(RolePermissionAddReq addReq) {
        Role role = roleMapper.getByName(addReq.getRoleName());
        if (role == null) {
            throw new BusinessException("角色不存在");
        }
        Permission permission = permissionMapper.getByPermission(addReq.getPermission());
        if (permission == null) {
            throw new BusinessException("权限不存在");
        }
        int count = roleMapper.existsPermission(addReq.getRoleName(), addReq.getPermission());
        if (count != 0) {
            throw new BusinessException("当前角色已经拥有该权限");
        }
        roleMapper.addPermission(addReq.getRoleName(), addReq.getPermission());
        return new RolePermissionAddRes(role, permission);
    }

    @Transactional
    public RolePermissionAddRes removeRolePermission(String roleName, String permissionStr) {
        Role role = roleMapper.getByName(roleName);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }
        Permission permission = permissionMapper.getByPermission(permissionStr);
        if (permission == null) {
            throw new BusinessException("权限不存在");
        }
        int count = roleMapper.existsPermission(roleName, permissionStr);
        if (count != 1) {
            throw new BusinessException("操作无效，当前角色未拥有该权限");
        }
        roleMapper.delPermission(roleName, permissionStr);
        return new RolePermissionAddRes(role, permission);
    }
}
